package com.lineage.server.clientpackets;

import com.lineage.commons.system.LanSecurityManager;
import com.lineage.config.Config;
import com.lineage.config.ConfigIpCheck;
import com.lineage.data.event.NetBarSet;
import com.lineage.echo.ClientExecutor;
import com.lineage.list.OnlineUser;
import com.lineage.server.datatables.lock.AccountReading;
import com.lineage.server.serverpackets.S_CommonNews;
import com.lineage.server.serverpackets.S_Disconnect;
import com.lineage.server.serverpackets.S_LoginResult;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Account;
import com.lineage.server.thread.GeneralThreadPool;
import java.util.Iterator;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class C_AuthLogin extends ClientBasePacket {
  private static final Log _log = LogFactory.getLog(C_AuthLogin.class);
  
  private static final String _check_accname = "abcdefghijklmnopqrstuvwxyz0123456789";
  
  private static final String _check_pwd = "abcdefghijklmnopqrstuvwxyz0123456789!_=+-?.#";
  
  public void start(byte[] decrypt, ClientExecutor client) {
    try {
      read(decrypt);
      boolean iserror = false;
      String loginName = readS().toLowerCase();
      if (loginName.length() > 12) {
        _log.warn("不合法的帐号长度:" + client.getIp().toString());
        client.set_error(client.get_error() + 1);
        return;
      } 
      int i = 0;
      while (i < loginName.length()) {
        String ch = loginName.substring(i, i + 1);
        if (!"abcdefghijklmnopqrstuvwxyz0123456789".contains(ch)) {
          _log.warn("不被允许的帐号字元!");
          iserror = true;
          break;
        } 
        i++;
      } 
      String password = readS();
      if (password.length() > 13) {
        _log.warn("不合法的密码长度:" + client.getIp().toString());
        client.set_error(client.get_error() + 1);
        return;
      } 
      int j = 0;
      while (j < password.length()) {
        String ch2 = password.substring(j, j + 1);
        if (!"abcdefghijklmnopqrstuvwxyz0123456789!_=+-?.#".contains(ch2.toLowerCase())) {
          _log.warn("不被允许的密码字元!");
          iserror = true;
          break;
        } 
        j++;
      } 
      if (!iserror) {
        checkLogin(client, loginName, password, false);
      } else {
        client.out().encrypt((ServerBasePacket)new S_LoginResult(10));
      } 
    } catch (Exception ex) {
      _log.error("login error ::", ex);
    } finally {
      over();
    } 
  }
  
  public void checkLogin(ClientExecutor client, String loginName, String password, boolean auto) {
    try {
      if (Config.TestServer) {
        if (!password.equals(Config.TestServerPassWords)) {
          _log.info("测试密码输入错误!");
          client.out().encrypt((ServerBasePacket)new S_LoginResult(8));
          return;
        } 
        _log.info("测试密码登入成功!");
      } 
      if (loginName == null)
        return; 
      if (loginName.equals(""))
        return; 
      if (password == null)
        return; 
      if (password.equals(""))
        return; 
      StringBuilder ip = client.getIp();
      StringBuilder mac = client.getMac();
      if (LanSecurityManager.BANNAMEMAP.containsKey(loginName)) {
        _log.warn("禁止登入帐号位置: account=" + loginName + " host=" + client.getIp());
        client.out().encrypt((ServerBasePacket)new S_LoginResult(26));
        KickTimeController kickTime = new KickTimeController(client, null);
        kickTime.schedule();
        return;
      } 
      boolean isError = false;
      L1Account account = AccountReading.get().getAccount(loginName);
      int tongip = ConfigIpCheck.ipcount;
      if (NetBarSet.EXIPLIST.containsKey(ip.toString()))
        tongip = ((Integer)NetBarSet.EXIPLIST.get(ip.toString())).intValue(); 
      if (tongip != 0) {
        int k = 0;
        Iterator<ClientExecutor> iterator = OnlineUser.get().all().iterator();
        while (iterator.hasNext()) {
          ClientExecutor tempClient = iterator.next();
          if (tempClient == null)
            continue; 
          if (tempClient.getAccount() == null) {
            _log.info("跳过取得空值：tempClient.getAccount() , 线上资料没有getAccount");
            continue;
          } 
          if (tempClient.getAccount().get_ip() == null) {
            _log.warn("玩家帐号:" + tempClient.getAccount().get_login() + " , 线上资料没有IP");
            continue;
          } 
          if (ip.toString().equalsIgnoreCase(tempClient.getAccount().get_ip()) && ++k > tongip - 1) {
            client.out().encrypt((ServerBasePacket)new S_LoginResult(39));
            return;
          } 
        } 
      } 
      if (account == null)
        if (Config.AUTO_CREATE_ACCOUNTS) {
          if (mac == null)
            mac = ip; 
          account = AccountReading.get().create(loginName, password, ip.toString(), mac.toString(), 
              "未建立超级密码");
        } else {
          if (auto) {
            client.out().encrypt((ServerBasePacket)new S_LoginResult(155));
            return;
          } 
          client.out().encrypt((ServerBasePacket)new S_LoginResult(8));
          isError = true;
        }  
      if (!account.get_password().equals(password) && !isError) {
        if (auto) {
          client.out().encrypt((ServerBasePacket)new S_LoginResult(149));
        } else {
          client.out().encrypt((ServerBasePacket)new S_LoginResult(8));
        } 
        isError = true;
      } 
      if (OnlineUser.get().isMax() && !isError) {
        _log.info("人数已达上限");
        client.out().encrypt((ServerBasePacket)new S_LoginResult(39));
        isError = true;
      } 
      if (isError) {
        int error = client.get_error();
        client.set_error(error + 1);
        return;
      } 
      ClientExecutor inGame = OnlineUser.get().get(loginName);
      if (inGame != null) {
        _log.info("相同帐号重复登 入: account=" + loginName + " host=" + ip);
        client.out().encrypt((ServerBasePacket)new S_LoginResult(22));
        KickTimeController kickTime2 = new KickTimeController(client, inGame);
        kickTime2.schedule();
      } else {
        if (account.get_server_no() != 0 && account.get_server_no() != Config.SERVERNO) {
          _log.info("帐号登入其他服务器: account=" + loginName + " host=" + ip + " 已经登入:" + 
              account.get_server_no() + "伺服器");
          client.out().encrypt((ServerBasePacket)new S_LoginResult(22));
          KickTimeController kickTime2 = new KickTimeController(client, null);
          kickTime2.schedule();
          return;
        } 
        if (account.is_isLoad()) {
          _log.info("相同帐号重复登入: account=" + loginName + " host=" + ip);
          client.out().encrypt((ServerBasePacket)new S_LoginResult(22));
          KickTimeController kickTime2 = new KickTimeController(client, null);
          kickTime2.schedule();
          return;
        } 
        if (OnlineUser.get().addClient(account, client)) {
          account.set_ip(ip.toString());
          if (mac != null)
            account.set_mac(mac.toString()); 
          AccountReading.get().updateLastActive(account);
          client.setAccount(account);
          OnlineUser.get().updateClient(account, client);
          client.out().encrypt((ServerBasePacket)new S_LoginResult(0));
          if (Config.NEWS) {
            delay(100, 100);
            client.out().encrypt((ServerBasePacket)new S_CommonNews());
          } else {
            delay(100, 100);
            C_CommonClick common = new C_CommonClick();
            common.start(null, client);
          } 
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public String getType() {
    return getClass().getSimpleName();
  }
  
  public void delay(int i, int j) {
    try {
      int rnd = (new Random()).nextInt(i) + j;
      Thread.sleep(rnd);
    } catch (Exception e) {
      _log.info("角色延迟登入系统出错");
    } 
  }
  
  private class KickTimeController implements Runnable {
    private ClientExecutor _kick1;
    
    private ClientExecutor _kick2;
    
    private KickTimeController(ClientExecutor kick1, ClientExecutor kick2) {
      this._kick1 = kick1;
      this._kick2 = kick2;
    }
    
    private void schedule() {
      GeneralThreadPool.get().execute(this);
    }
    
    public void run() {
      try {
        Thread.sleep(1000L);
        this._kick1.out().encrypt((ServerBasePacket)new S_Disconnect());
        Thread.sleep(1000L);
        this._kick1.set_error(10);
        if (this._kick2 != null)
          this._kick2.set_error(10); 
      } catch (InterruptedException e) {
        C_AuthLogin._log.error(e.getLocalizedMessage(), e);
      } 
    }
  }
}
